#include "SQLListExpr.h"
#include "../../visitor/SQLASTVisitor.h"

SQLListExpr::SQLListExpr()
{
  items = std::make_shared<std::list<SQLExpr_ptr>>();
}

SQLListExpr::SQLListExpr(SQLExpr_list_ptr  items)
{
  this->items = std::make_shared<std::list<SQLExpr_ptr>>();
  for (SQLExpr_ptr item : *items)
  {
    item->setParent(SharedObject(SQLListExpr));
    this->items->push_back(item);
  }
}

SQLListExpr::~SQLListExpr()
{

  // for (std::list<SQLExpr_ptr >::iterator it = items->begin(); it != items->end(); ++it)
  // {
  //   delete *it;
  // }
  // items->clear();
}

SQLExpr_list_ptr  SQLListExpr::getItems()
{
  return items;
}

void SQLListExpr::accept0(SQLASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(SQLListExpr)))
  {
    auto it = items->begin();
    for (size_t i = 0; i < items->size(); i++)
    {
      std::advance(it, i); // 迭代器前进i个元素，注意i是从0开始
      if ((*it) != NULL)
      {
        (*it)->accept(visitor);
      }
    }
  }
  visitor->endVisit(SharedObject(SQLListExpr));
}

void SQLListExpr::addItem(SQLExpr_ptr item)
{
  if (item != NULL)
  {
    item->setParent(SharedObject(SQLListExpr));
  }
  this->items->push_back(item);
}
int SQLListExpr::hashCode()
{
  int prime = 31;
  int result = 1;
  // result = prime * result + ((items.empty()) ? 0 : items.hashCode());
  result = prime * result + 0;
  return result;
}

bool SQLListExpr::equals(Object_ptr obj)
{
  if (this == obj.get())
  {
    return true;
  }
  if (obj == NULL)
  {
    return false;
  }
  if (getClass() != obj->getClass())
  {
    return false;
  }
  SQLListExpr_ptr other = std::dynamic_pointer_cast<SQLListExpr>(obj);
  if (items->empty())
  {
    if (!other->items->empty())
    {
      return false;
    }
    // } else if (!items.equals(other->items)) {
    // 	return BOOL::FALSE;
  }
  return true;
}

SQLObject_ptr SQLListExpr::clone()
{
  SQLObject_ptr clone_tmp = SQLListExpr_ptr(new SQLListExpr());
  SQLListExpr_ptr x = std::dynamic_pointer_cast<SQLListExpr>(clone_tmp);
  // SQLListExpr *x = new SQLListExpr();
  for (SQLExpr_ptr item : *items)
  {
    SQLExpr_ptr item2 = std::dynamic_pointer_cast<SQLExpr>(item->clone());
    item2->setParent(x);
    x->items->push_back(item2);
  }
  return x;
}

BOOL_ptr SQLListExpr::replace(SQLExpr_ptr expr, SQLExpr_ptr target)
{
  for (int i = 0; i < items->size(); i++)
  {
    auto it = items->begin();
    std::advance(it, i);
    if ((*it) == expr)
    {
      target->setParent(SharedObject(SQLListExpr));
      items->insert(it, target);
      return BOOL::TRUE;
    }
  }
  return BOOL::FALSE;
}